//
//  YCPhotoTestManager.swift
//  YCCamera
//
//  Created by Billy on 2024/5/17.
//

import UIKit
import Photos
import Vision

class YCPhotoTestManager {

    public class func fetchMonthlyPhotoCollections(completion: @escaping ([(month: String, photos: [(asset: PHAsset, feature: VNFeaturePrintObservation?)])]) -> Void) {
        // 请求访问照片库的权限
        PHPhotoLibrary.requestAuthorization { status in
            if status == .authorized {
                
                DispatchQueue.global(qos: .userInitiated).async {
                    // 创建照片库的请求对象
                    let fetchOptions = PHFetchOptions()
                    // 按创建日期降序排序
                    fetchOptions.sortDescriptors = [NSSortDescriptor(key: "creationDate", ascending: false)]
                    
                    // 获取所有照片
                    let allPhotos = PHAsset.fetchAssets(with: .image, options: fetchOptions)
                    
                    // 创建一个数组来存储每个月的照片合集
                    var monthlyPhotoCollections: [(month: String, photos: [(asset: PHAsset, feature: VNFeaturePrintObservation?)])] = []
                    
                    // 日期格式化器，用于提取月份信息
                    let dateFormatter = DateFormatter()
                    dateFormatter.dateFormat = "yyyy-MM"
                    
                    // 辅助函数，用于在数组中查找指定月份
                    func findCollection(for month: String) -> Int? {
                        return monthlyPhotoCollections.firstIndex { $0.month == month }
                    }
                    
                    // 创建一个调度组
                    let dispatchGroup = DispatchGroup()
                    
                    // 遍历所有照片
                    allPhotos.enumerateObjects { (asset, _, _) in
                        if let creationDate = asset.creationDate {
                            // 获取照片的创建日期的月份信息
                            let monthKey = dateFormatter.string(from: creationDate)
                            
                            // 查找数组中是否已经有该月份的集合
                            if let index = findCollection(for: monthKey) {
                                // 如果有，添加到现有的集合中
                                dispatchGroup.enter()
                                self.extractFeature(for: asset) { feature in
                                    monthlyPhotoCollections[index].photos.append((asset, feature))
                                    dispatchGroup.leave()
                                }
                            } else {
                                // 如果没有，创建新的集合并添加到数组中
                                dispatchGroup.enter()
                                self.extractFeature(for: asset) { feature in
                                    monthlyPhotoCollections.append((month: monthKey, photos: [(asset, feature)]))
                                    dispatchGroup.leave()
                                }
                            }
                        }
                    }
                    
                    // 在主线程中调用completion，返回每个月的照片合集
                    dispatchGroup.notify(queue: .main) {
                        completion(monthlyPhotoCollections)
                    }
                }
                
                
            } else {
                // 处理未授权的情况，返回空数组
                DispatchQueue.main.async {
                    completion([])
                }
            }
        }
    }
    
    
    public class func extractFeature(for asset: PHAsset, completion: @escaping (VNFeaturePrintObservation?) -> Void) {
        let imageManager = PHImageManager.default()
        let options = PHImageRequestOptions()
        options.isSynchronous = true
        options.deliveryMode = .fastFormat
        options.resizeMode = .fast
        
        imageManager.requestImage(for: asset, targetSize: CGSize(width: 50, height: 50), contentMode: .aspectFill, options: options) { image, info in
            guard let cgImage = image?.cgImage else {
                completion(nil)
                return
            }
            
            let requestHandler = VNImageRequestHandler(cgImage: cgImage, options: [:])
            let request = VNGenerateImageFeaturePrintRequest { request, error in
                guard let results = request.results as? [VNFeaturePrintObservation], let featurePrint = results.first else {
                    completion(nil)
                    return
                }
                completion(featurePrint)
            }
            
            do {
                try requestHandler.perform([request])
            } catch {
                completion(nil)
            }
        }
    }
}
